<template>
  <view class="container">
    <!-- 顶部导航栏 -->
    <view class="header">
      <view class="header-left">
        <view class="global-header-left" @click="goBack">
          <view class="global-back-button">
            <text class="global-back-icon">‹</text>
          </view>
          <text class="global-back-text">返回</text>
        </view>
      </view>
      <view class="header-center">
        <text class="header-title">线下徒步报名</text>
        <!-- {{ isReserved ? '已预约' : '未预约' }} -->
      </view>
    </view>

    <!-- 未预约状态 - 内容区域 -->
    <scroll-view class="content" scroll-y="true" v-if="!isReserved">
      <!-- 活动信息 -->
      <view class="activity-info-section">
        <view class="activity-header">
          <text class="activity-title">2025年第十一季体彩爱行走线下徒步</text>
          <text class="activity-rules" @click="showRulesModal">活动规则</text>
        </view>

        <view class="activity-detail">
          <!-- 日期时间 -->
          <view class="detail-item">
            <image
              class="detail-icon"
              :src="getImageUrl('资源 1-3.png')"
              mode="aspectFit"
            ></image>
            <view class="detail-text-wrapper">
              <text class="detail-text">2025年11月22日</text>
              <text class="detail-text">13:00-16:00</text>
            </view>
          </view>
          <!-- 位置 -->
          <view class="detail-item">
            <image
              class="detail-icon"
              :src="getImageUrl('资源 1-2.png')"
              mode="aspectFit"
            ></image>
            <view class="detail-text-wrapper">
              <text class="detail-text">江苏省镇江市</text>
              <text class="detail-text">西津渡(鉴园广场)</text>
            </view>
          </view>
          <!-- 参与人数 -->
          <view class="detail-item">
            <image
              class="detail-icon"
              :src="getImageUrl('资源 1-1.png')"
              mode="aspectFit"
            ></image>
            <view class="detail-text-wrapper">
              <text class="detail-text">限150人参与</text>
              <text class="detail-text">(凭身份证件入场)</text>
            </view>
          </view>
        </view>
      </view>

      <!-- 填写报名信息 -->
      <view class="form-section">
        <text class="section-title">填写报名信息</text>

        <!-- 真实姓名 -->
        <view class="form-item">
          <text class="form-label">真实姓名</text>
          <input
            class="form-input"
            type="text"
            v-model="formData.realName"
            placeholder="请输入您的真实姓名请与身份证姓名一致"
            placeholder-style="color: #CCCCCC"
          />
        </view>

        <!-- 手机号码 -->
        <view class="form-item">
          <text class="form-label">手机号码</text>
          <view class="phone-input-wrapper">
            <input
              class="form-input phone-input"
              type="number"
              v-model="formData.mobile"
              placeholder="请输入手机号码"
              placeholder-style="color: #CCCCCC"
            />
            <!-- #ifdef MP-WEIXIN -->
            <button
              class="wechat-auth-btn"
              open-type="getPhoneNumber"
              @getphonenumber="handleGetPhoneNumber"
            >
              微信授权获取
            </button>
            <!-- #endif -->
            <!-- #ifndef MP-WEIXIN -->
            <text class="wechat-auth-text" @click="getWechatPhone"
              >微信授权获取</text
            >
            <!-- #endif -->
          </view>
        </view>

        <!-- 身份证号码 -->
        <view class="form-item">
          <text class="form-label">身份证号码</text>
          <input
            class="form-input"
            type="text"
            v-model="formData.idCard"
            placeholder="请输入身份证号码"
            placeholder-style="color: #CCCCCC"
          />
          <text class="form-hint"
            >报名成功后，工作人员将通知参与者，并为其办理保险。</text
          >
          <text class="form-hint"
            >保险办理将以参与者报名时提交的个人信息为准。</text
          >
        </view>
      </view>
    </scroll-view>

    <!-- 已预约状态 - 内容区域（从接口获取） -->
    <scroll-view
      class="content content-reserved"
      scroll-y="true"
      v-if="isReserved"
    >
      <!-- 活动信息 -->
      <view class="activity-info-section activity-info-reserved">
        <view class="activity-header">
          <text class="activity-title">2025年第十一季体彩爱行走线下徒步</text>
          <text class="activity-rules" @click="showRulesModal">活动规则</text>
        </view>

        <!-- 预约成功标签 -->
        <view class="reserved-success-tag">
          <text class="reserved-success-text">报名信息已提交</text>
        </view>

        <view class="activity-detail activity-detail-reserved">
          <view class="detail-item-reserved">
            <image
              class="detail-icon-reserved"
              :src="getImageUrl('资源 1-3.png')"
              mode="aspectFit"
            ></image>
            <text class="detail-text-reserved">2025年11月22日13:00-16:00</text>
          </view>
          <view class="detail-item-reserved">
            <image
              class="detail-icon-reserved"
              :src="getImageUrl('资源 1-2.png')"
              mode="aspectFit"
            ></image>
            <text class="detail-text-reserved"
              >江苏省镇江市西津渡(鉴园广场)</text
            >
          </view>
        </view>
      </view>

      <!-- 分隔线 -->
      <view class="reserved-divider"></view>

      <!-- 预约详情 -->
      <view class="reservation-details-section reservation-details-reserved">
        <text class="section-title section-title-reserved">预约详情</text>
        <view class="reservation-detail-card">
          <view class="detail-row-reserved">
            <text class="detail-label-reserved">姓名</text>
            <text class="detail-value-reserved">{{
              reservationData.realName || "乐小星"
            }}</text>
          </view>
          <view class="detail-row-reserved">
            <text class="detail-label-reserved">手机号码</text>
            <text class="detail-value-reserved">{{
              reservationData.mobile || "138XXXX5678"
            }}</text>
          </view>
          <view class="detail-row-reserved">
            <text class="detail-label-reserved">身份证号码</text>
            <text class="detail-value-reserved">{{
              reservationData.idCard || "320XXXXXXXXXXX1234"
            }}</text>
          </view>
          <view class="detail-row-reserved">
            <text class="detail-label-reserved">预约时间</text>
            <text class="detail-value-reserved">{{
              reservationData.reservationTime || "2025-11-17 15:30"
            }}</text>
          </view>
        </view>
      </view>
    </scroll-view>

    <!-- 底部按钮 -->
    <view class="footer">
      <button class="submit-btn" v-if="!isReserved" @click="submitReservation">
        提交
      </button>
      <!-- <button class="cancel-btn cancel-btn-reserved" v-if="isReserved" @click="cancelReservation">取消预约</button> -->
    </view>

    <!-- 成功弹窗（样式对齐 playlist-share.vue） -->
    <view
      class="success-modal-mask"
      v-if="showSuccessModal"
      @click="closeSuccessModal"
    >
      <view class="success-modal-content" @click.stop>
        <!-- 关闭按钮 -->
        <view class="close-button" @click="closeSuccessModal">
          <image
            class="close-icon"
            src="/static/资源 1-8.png"
            mode="aspectFit"
          ></image>
        </view>
        <!-- 背景图片容器 -->
        <view class="success-modal-bg-wrapper">
          <image
            class="success-modal-bg"
            src="/static/box.png"
            mode="aspectFit"
            :style="{ width: '600rpx', height: '800rpx' }"
          ></image>
          <!-- 吉祥物图片 -->
          <image
            class="success-modal-mascot"
            :src="getModalMascotImage('点击查看')"
            mode="aspectFit"
          ></image>
          <!-- 提示文字 -->
          <view
            class="success-text small"
            :style="{ color: getModalTextColor('点击查看') }"
          >
            报名信息已提交
          </view>
          <!-- 按钮 -->
          <view class="lottery-button" @click="viewDetails"> 点击查看 </view>
        </view>
      </view>
    </view>

    <!-- 规则弹窗 -->
    <view class="modal-overlay" v-if="showRules" @click="hideRulesModal">
      <view class="modal-outer" @click.stop>
        <!-- 外层：标题和渐变色背景 -->
        <view class="modal-header-outer">
          <text class="modal-title-outer">线下活动规则</text>
        </view>

        <!-- 内层：具体内容和按钮 -->
        <view class="modal-inner">
          <!-- 内容区域 -->
          <scroll-view class="modal-content-scroll" scroll-y="true">
            <view class="modal-body">
              <view class="rule-item">
                <text class="rule-title">一、活动时间</text>
                <text class="rule-detail">2025年11月22日-23日</text>
              </view>
              <view class="rule-item">
                <text class="rule-title">二、活动地点</text>
                <text class="rule-detail">江苏省镇江市西津渡（鉴园广场）</text>
              </view>
              <view class="rule-item">
                <text class="rule-title">三、活动内容</text>
                <text class="rule-detail"
                  >（一）徒步活动\n1.报名时间\n2025年11月17日至11月21日
                  9:00-23:00\n\n2.活动对象\n报名者须为18-60周岁，招募150人，报满即止。\n\n3.报名方式\n关注江苏体彩微信订阅号，点击"爱行走"菜单进入活动页面报名。\n\n4.活动时间\n2025年11月22日13:00-16:00\n\n5.活动流程（以现场实际为准）\n13:00-13:55
                  签到\n13:55-14:00 开场表演\n14:00-14:13
                  活动启动仪式\n14:13-14:20 现场热身\n14:20-16:00
                  公益步行\n16:00
                  活动结束\n\n6.徒步路线\n本次徒步活动共设有三个打卡点，步行路线上均有方向指引。</text
                >
                <view class="rule-image-wrapper">
                  <image
                    class="rule-map-image"
                    src="/static/map.png"
                    mode="widthFix"
                  ></image>
                </view>
                <text class="rule-detail"
                  >7.奖品设置\n成功报名徒步活动（以工作人员通知为准），且按时到达场地签到，并按照活动规则完成行走路线的用户，可获得2025年第十一季体彩爱行走参赛包1份。\n\n8.注意事项\n（1）徒步参与者须在活动当天16:00前完成。\n（2）报名成功后，工作人员将通知参与者，并为其办理保险。保险办理将以参与者报名时提交的个人信息为准。\n\n（二）互动活动\n11月22日13:00-20:30，11月23日10:00-20:30，现场将开展体彩互动活动，设有公益展示区、拍照打卡区、游戏区等。参与互动活动，将有机会获取体彩爱行走周边好礼。互动活动，无需报名，参与方式以现场实际为准。\n\n（三）演出活动\n11月23日13:20-16:00，现场将进行腾讯音乐娱乐集团TME《和我一起唱》及其他演出。观看演出无需报名。</text
                >
              </view>
              <view class="rule-item">
                <text class="rule-title">四、交通指引</text>
                <text class="rule-detail"
                  >（一）公共交通前往\n1.镇江站出发\n——线路1：从镇江站北广场步行约370米到"火车站(北)"站，乘坐15路公交（往白娘子园公交站方向），到"西津渡"站，下车后步行抵达。\n——线路2：从镇江站南广场步行约250米到"火车站南广场"站，乘坐17路公交（往疏港路公交站方向），到"和平路"站，下车后步行840米抵达。\n2.镇江南站出发\n从镇江南站乘坐高铁快1线、208路等公交到"牌湾"站，换乘67路或17路公交到西津渡站点，下车后步行抵达。\n\n（二）自驾前往\n打开导航APP，直接搜索目的地"镇江市-西津渡历史文化街区地下停车场-出入口"（鉴园广场专属地下停车点），跟随实时导航行驶即可。</text
                >
              </view>
              <view class="rule-item">
                <text class="rule-title">五、温馨提示</text>
                <text class="rule-detail"
                  >参与第十一季体彩爱行走线下活动，即视为同意被江苏体彩现场拍摄，并同意江苏体彩无偿使用其肖像、声音，用于本次活动的录音、录像、印刷品等宣传推广用途。</text
                >
              </view>
              <view class="rule-item">
                <text class="rule-title">六、咨询方式</text>
                <text class="rule-detail"
                  >活动统一咨询电话：025-86896060\n（工作时间：周一至周五
                  9:00—12:00，14:00—17:00）</text
                >
              </view>
            </view>
          </scroll-view>

          <!-- 底部按钮 -->
          <view class="modal-footer">
            <button class="modal-btn" @click="hideRulesModal">我已知晓</button>
          </view>
        </view>
      </view>
    </view>
  </view>
</template>

<script>
import { decryptPhoneNumber as decryptPhoneFromAPI } from "@/api/user";
import { getImageUrl as getImageUrlFromConfig } from "@/api/config";
import { userStore } from "@/api/userStore";
import { signUp, cancelOfflineActivity } from "@/api/activity";

export default {
  data() {
    return {
      isReserved: false, // 是否已预约（从接口获取）
      showSuccessModal: false,
      showRules: false, // 规则弹窗显示状态
      formData: {
        realName: "",
        mobile: "",
        idCard: "",
      },
      reservationData: {
        realName: "",
        mobile: "",
        idCard: "",
        reservationTime: "",
      },
    };
  },
  onLoad() {
    // 确保所有数据正确初始化
    this.formData = this.formData || {
      realName: "",
      mobile: "",
      idCard: "",
    };
    this.reservationData = this.reservationData || {
      realName: "",
      mobile: "",
      idCard: "",
      reservationTime: "",
    };
    // 页面加载时从 userStore 获取预约状态
    this.loadReservationStatus();
  },
  methods: {
    getImageUrl(imagePath) {
      if (!imagePath) return "";
      try {
        return getImageUrlFromConfig(imagePath);
      } catch (error) {
        console.error("getImageUrl error:", error);
        return "";
      }
    },
    /**
     * 获取弹窗吉祥物图片（对齐 playlist-share.vue 的通用函数）
     * @param {string} buttonText - 按钮文本
     * @returns {string} 返回图片路径
     */
    getModalMascotImage(buttonText) {
      // 当按钮是"立即捐步"时，使用资源 4.png，否则使用资源 33-8.png
      if (buttonText === "立即捐步") {
        return "/static/资源 4.png";
      }
      return "/static/资源 33-8.png";
    },
    /**
     * 获取弹窗文字颜色（对齐 playlist-share.vue 的通用函数）
     * @param {string} buttonText - 按钮文本
     * @returns {string} 返回颜色值
     */
    getModalTextColor(buttonText) {
      // 当按钮是"立即捐步"时，使用蓝色，否则使用红色
      if (buttonText === "立即捐步") {
        return "#1b6ec1";
      }
      return "#f03c32";
    },
    /**
     * 从 userStore 加载预约状态
     * 如果 signUpInfo 存在且关键字段不是 "0" 之类的无效值，则表示已预约
     */
    loadReservationStatus() {
      try {
        const loginData = userStore.getLoginData();
        if (loginData && loginData.signUpInfo) {
          const signUpInfo = loginData.signUpInfo;
          // 检查关键字段是否存在且不是 "0" 之类的无效值
          const name = String(signUpInfo.name || "").trim();
          const phone = String(signUpInfo.phone || "").trim();
          const idCard = String(signUpInfo.idCard || "").trim();

          const hasValidName = name !== "" && name !== "0";
          const hasValidPhone = phone !== "" && phone !== "0";
          const hasValidIdCard = idCard !== "" && idCard !== "0";

          // 如果至少有一个关键字段有效，则判定为已预约
          if (hasValidName || hasValidPhone || hasValidIdCard) {
            // 设置已预约状态
            this.isReserved = true;
            // 填充预约数据（用于显示）
            this.reservationData = {
              realName: name || "",
              mobile: phone
                ? phone.replace(/(\d{3})\d{4}(\d{4})/, "$1XXXX$2")
                : "", // 脱敏处理
              idCard: idCard
                ? idCard.replace(/(\d{6})\d{8}(\d{4})/, "$1XXXXXXXX$2")
                : "", // 脱敏处理
              reservationTime:
                signUpInfo.signUpTime &&
                signUpInfo.signUpTime !== "0" &&
                signUpInfo.signUpTime !== 0
                  ? this.formatDateTime(
                      new Date(parseInt(signUpInfo.signUpTime))
                    )
                  : "",
            };
          } else {
            // 未预约（signUpInfo 存在但都是无效值）
            this.isReserved = false;
          }
        } else {
          // 未预约（signUpInfo 不存在）
          this.isReserved = false;
        }
      } catch (error) {
        console.error("加载预约状态失败", error);
        this.isReserved = false;
      }
    },
    /**
     * 更新 userStore 中的 signUpInfo
     * @param {Object|null} signUpInfo 预约信息，如果为 null 则清空
     */
    updateSignUpInfoInStore(signUpInfo) {
      try {
        const loginData = userStore.getLoginData();
        if (loginData) {
          // 创建新的 loginData 对象，更新 signUpInfo
          const updatedLoginData = {
            ...loginData,
            signUpInfo: signUpInfo || undefined,
          };
          // 更新到 userStore
          userStore.setLoginData(updatedLoginData);
          console.log("已更新 userStore 中的 signUpInfo", signUpInfo);
        } else {
          console.warn("无法更新 signUpInfo：loginData 不存在");
        }
      } catch (error) {
        console.error("更新 signUpInfo 失败", error);
      }
    },
    goBack() {
      uni.navigateBack();
    },
    showRulesModal() {
      this.showRules = true;
    },
    hideRulesModal() {
      this.showRules = false;
    },
    // 处理微信授权获取手机号
    async handleGetPhoneNumber(e) {
      console.log("获取手机号事件", e);

      // 检查是否取消授权
      if (e.detail.errMsg && e.detail.errMsg.includes("deny")) {
        uni.showToast({
          title: "已取消授权",
          icon: "none",
        });
        return;
      }

      // 新版本微信小程序直接返回 code，需要后端解密
      if (e.detail.code) {
        try {
          uni.showLoading({
            title: "获取中...",
          });

          // 调用后端接口解密手机号
          const phoneNumber = await this.decryptPhoneNumber(e.detail.code);

          if (phoneNumber) {
            // 将手机号填入表单
            this.formData.mobile = phoneNumber;
            uni.showToast({
              title: "获取成功",
              icon: "success",
            });
          } else {
            throw new Error("获取手机号失败");
          }
        } catch (error) {
          console.error("获取手机号失败", error);
          // 检查是否是404错误（后端接口未实现）
          const errorMsg = error.message || "";
          const errorCode = error.code || error.statusCode || "";

          if (
            errorCode === 404 ||
            errorMsg.includes("404") ||
            errorMsg.includes("not found")
          ) {
            uni.showModal({
              title: "功能暂不可用",
              content:
                "微信授权获取手机号功能需要后端接口支持。请先手动输入手机号码，或联系后端开发人员实现 /jstc/v1/phone_decrypt 接口。",
              showCancel: false,
              confirmText: "知道了",
            });
          } else {
            uni.showToast({
              title: errorMsg || "获取手机号失败，请手动输入",
              icon: "none",
              duration: 3000,
            });
          }
        } finally {
          uni.hideLoading();
        }
      } else {
        // 旧版本兼容处理（包含 encryptedData 和 iv）
        if (e.detail.encryptedData && e.detail.iv) {
          try {
            uni.showLoading({
              title: "获取中...",
            });

            // 调用后端接口解密手机号（旧版本）
            const phoneNumber = await this.decryptPhoneNumberOld(
              e.detail.encryptedData,
              e.detail.iv
            );

            if (phoneNumber) {
              this.formData.mobile = phoneNumber;
              uni.showToast({
                title: "获取成功",
                icon: "success",
              });
            } else {
              throw new Error("获取手机号失败");
            }
          } catch (error) {
            console.error("获取手机号失败", error);
            // 检查是否是404错误（后端接口未实现）
            const errorMsg = error.message || "";
            const errorCode = error.code || error.statusCode || "";

            if (
              errorCode === 404 ||
              errorMsg.includes("404") ||
              errorMsg.includes("not found")
            ) {
              uni.showModal({
                title: "功能暂不可用",
                content:
                  "微信授权获取手机号功能需要后端接口支持。请先手动输入手机号码，或联系后端开发人员实现 /jstc/v1/phone_decrypt 接口。",
                showCancel: false,
                confirmText: "知道了",
              });
            } else {
              uni.showToast({
                title: errorMsg || "获取手机号失败，请手动输入",
                icon: "none",
                duration: 3000,
              });
            }
          } finally {
            uni.hideLoading();
          }
        } else {
          uni.showToast({
            title: "获取手机号失败，请手动输入",
            icon: "none",
          });
        }
      }
    },
    /**
     * 解密手机号（新版本，使用 code）
     *
     * 根据微信官方文档：https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/user-info/phone-number/getPhoneNumber.html
     *
     * 前端需要做的事情：
     * 1. 使用 <button open-type="getPhoneNumber"> 按钮
     * 2. 绑定 @getphonenumber 事件处理函数
     * 3. 接收返回的 code（新版本）或 encryptedData + iv（旧版本，已废弃）
     * 4. 将 code 发送到后端接口进行解密
     *
     * 后端接口需要做的事情：
     * 1. 接收参数：{ code: string, openid?: string }（openid 为可选参数）
     * 2. 使用 access_token 调用微信 API：
     *    POST https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token=ACCESS_TOKEN
     *    Body: { code: string, openid?: string }
     * 3. 返回格式：{ phoneNumber: string }
     *
     * 注意：
     * - code 只能使用一次，有效期为 5 分钟
     * - 每个 code 只能使用一次
     * - openid 是可选参数，如果后端需要可以传递
     */
    async decryptPhoneNumber(code) {
      try {
        // 尝试获取 openid（可选参数，根据微信文档）
        const loginData = userStore.getLoginData();
        const openid = loginData && loginData.openid ? loginData.openid : null;

        // 构建请求参数
        const requestData = { code: code || "" };
        if (openid) {
          requestData.openid = openid;
        }

        // 不显示 loading（因为已经在 handleGetPhoneNumber 中显示了）
        const response = await decryptPhoneFromAPI(requestData, {
          showLoading: false,
        });

        // 返回手机号（后端返回格式：{phone: "****"}）
        return response.phone || response.phoneNumber;
      } catch (error) {
        console.error("解密手机号失败", error);
        throw error;
      }
    },
    /**
     * 解密手机号（旧版本，使用 encryptedData 和 iv）
     *
     * 注意：此方法需要后端实现 /jstc/v1/phone_decrypt 接口
     * 后端接口需要：
     * 1. 接收参数：{ encryptedData: string, iv: string }
     * 2. 使用 session_key 解密数据（AES-128-CBC）
     * 3. 返回格式：{ phoneNumber: string }
     *
     * 注意：旧版本微信小程序已废弃，建议使用新版本的 code 方式
     */
    async decryptPhoneNumberOld(encryptedData, iv) {
      try {
        // 不显示 loading（因为已经在 handleGetPhoneNumber 中显示了）
        const response = await decryptPhoneFromAPI(
          {
            encryptedData,
            iv,
          },
          {
            showLoading: false,
          }
        );

        // 返回手机号（后端返回格式：{phone: "****"}）
        return response.phone || response.phoneNumber;
      } catch (error) {
        console.error("解密手机号失败", error);
        throw error;
      }
    },
    // 兼容非微信小程序环境
    getWechatPhone() {
      uni.showToast({
        title: "请在微信小程序中使用",
        icon: "none",
      });
    },
    /**
     * 表单校验
     * @returns {boolean} 校验是否通过
     */
    validateForm() {
      // 校验真实姓名
      if (!this.formData.realName || this.formData.realName.trim() === "") {
        uni.showToast({
          title: "请输入真实姓名",
          icon: "none",
        });
        return false;
      }

      // 校验手机号码
      if (!this.formData.mobile || this.formData.mobile.trim() === "") {
        uni.showToast({
          title: "请输入手机号码",
          icon: "none",
        });
        return false;
      }
      // 手机号格式校验：1开头的11位数字
      if (!/^1[3-9]\d{9}$/.test(this.formData.mobile.trim())) {
        uni.showToast({
          title: "请输入正确的手机号码",
          icon: "none",
        });
        return false;
      }

      // 校验身份证号码
      if (!this.formData.idCard || this.formData.idCard.trim() === "") {
        uni.showToast({
          title: "请输入身份证号码",
          icon: "none",
        });
        return false;
      }
      // 身份证号格式校验：18位身份证号
      const idCardRegex =
        /^[1-9]\d{5}(18|19|20)\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01])\d{3}[\dXx]$/;
      if (!idCardRegex.test(this.formData.idCard.trim())) {
        uni.showToast({
          title: "请输入正确的身份证号码",
          icon: "none",
        });
        return false;
      }

      return true;
    },
    /**
     * 提交预约
     */
    async submitReservation() {
      // 表单校验
      if (!this.validateForm()) {
        return;
      }

      try {
        // 获取当前时间戳（毫秒数，int64）
        const signUpTime = new Date().getTime();
        // 格式化预约时间用于显示：YYYY-MM-DD HH:mm:ss
        const formattedTime = this.formatDateTime(new Date());

        // 从身份证号码计算年龄
        const age = this.calculateAgeFromIdCard(this.formData.idCard.trim());
        if (age === 0) {
          uni.showToast({
            title: "无法从身份证号码计算年龄，请检查身份证号码是否正确",
            icon: "none",
            duration: 3000,
          });
          return;
        }

        // 构建请求参数
        const requestData = {
          name: this.formData.realName.trim(),
          phone: this.formData.mobile.trim(),
          age: age,
          idCard: this.formData.idCard.trim(),
          signUpTime: signUpTime,
        };

        // 调用后端接口提交预约
        const response = await signUp(requestData);

        // 检查响应结果
        if (response && response.success) {
          // 保存预约数据（用于显示）
          this.reservationData = {
            realName: this.formData.realName,
            mobile: this.formData.mobile.replace(
              /(\d{3})\d{4}(\d{4})/,
              "$1XXXX$2"
            ), // 脱敏处理
            idCard: this.formData.idCard.replace(
              /(\d{6})\d{8}(\d{4})/,
              "$1XXXXXXXX$2"
            ), // 脱敏处理
            reservationTime: formattedTime,
          };

          // 更新 userStore 中的 signUpInfo
          this.updateSignUpInfoInStore({
            name: this.formData.realName.trim(),
            phone: this.formData.mobile.trim(),
            idCard: this.formData.idCard.trim(),
            signUpTime: signUpTime.toString(),
            isSignedUp: true,
          });

          // 显示成功弹窗
          this.showSuccessModal = true;
        } else {
          throw new Error("提交预约失败");
        }
      } catch (error) {
        console.error("提交预约失败", error);
        const errorMsg =
          error.message || error.msg || "提交预约失败，请稍后重试";
        uni.showToast({
          title: errorMsg,
          icon: "none",
          duration: 3000,
        });
      }
    },
    closeSuccessModal() {
      this.showSuccessModal = false;
      // 提交成功后，更新预约状态
      this.isReserved = true;
    },
    viewDetails() {
      // 关闭弹窗并切换到已预约界面（closeSuccessModal 中已设置 isReserved = true）
      this.closeSuccessModal();
    },
    /**
     * 取消预约
     * 调用 /jstc/v1/cancel_offline_activity 接口
     */
    cancelReservation() {
      uni.showModal({
        title: "提示",
        content: "确认取消预约？",
        success: async (res) => {
          if (res.confirm) {
            try {
              // 调用取消预约接口
              const response = await cancelOfflineActivity();

              // 检查响应结果
              if (response && response.success) {
                // 重置状态
                this.isReserved = false;
                this.formData = {
                  realName: "",
                  mobile: "",
                  idCard: "",
                };
                this.reservationData = {
                  realName: "",
                  mobile: "",
                  idCard: "",
                  reservationTime: "",
                };

                // 清空 userStore 中的 signUpInfo
                this.updateSignUpInfoInStore(null);

                uni.showToast({
                  title: "已取消预约",
                  icon: "success",
                });
              } else {
                throw new Error("取消预约失败");
              }
            } catch (error) {
              console.error("取消预约失败", error);
              const errorMsg =
                error.message || error.msg || "取消预约失败，请稍后重试";
              uni.showToast({
                title: errorMsg,
                icon: "none",
                duration: 3000,
              });
            }
          }
        },
      });
    },
    /**
     * 从身份证号码计算年龄
     * @param {string} idCard 身份证号码
     * @returns {number} 年龄，如果无法计算则返回 0
     */
    calculateAgeFromIdCard(idCard) {
      if (!idCard || idCard.trim().length < 10) {
        return 0;
      }

      try {
        const idCardStr = idCard.trim();
        // 18位身份证：前6位地区码，接下来8位是出生日期（YYYYMMDD）
        // 出生年份是第7-10位（索引6-9）
        let birthYear = 0;

        if (idCardStr.length === 18) {
          // 18位身份证
          birthYear = parseInt(idCardStr.substring(6, 10));
        } else if (idCardStr.length === 15) {
          // 15位身份证（旧版）：前6位地区码，接下来6位是出生日期（YYMMDD）
          // 出生年份是第7-8位（索引6-7），需要判断是19xx还是20xx
          const year = parseInt(idCardStr.substring(6, 8));
          birthYear = year < 30 ? 2000 + year : 1900 + year;
        } else {
          return 0;
        }

        // 计算年龄
        const currentYear = new Date().getFullYear();
        const age = currentYear - birthYear;

        // 年龄合理性校验
        if (age < 0 || age > 150) {
          return 0;
        }

        return age;
      } catch (error) {
        console.error("计算年龄失败", error);
        return 0;
      }
    },
    /**
     * 格式化日期时间
     * @param {Date} date 日期对象
     * @returns {string} 格式化的日期时间字符串，格式：YYYY-MM-DD HH:mm:ss
     */
    formatDateTime(date) {
      const year = date.getFullYear();
      const month = String(date.getMonth() + 1).padStart(2, "0");
      const day = String(date.getDate()).padStart(2, "0");
      const hours = String(date.getHours()).padStart(2, "0");
      const minutes = String(date.getMinutes()).padStart(2, "0");
      const seconds = String(date.getSeconds()).padStart(2, "0");
      return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
    },
  },
};
</script>

<style scoped>
.container {
  min-height: 100vh;
  background-color: #93d3f4;
  display: flex;
  flex-direction: column;
  padding: 0;
}

/* 顶部导航栏 */
.header {
  background: transparent;
  padding: var(--status-bar-height, 44rpx) 30rpx 20rpx;
  padding-top: 104rpx;
  display: flex;
  align-items: center;
  justify-content: space-between;
  position: relative;
  z-index: 1000;
}

.header-left {
  flex: 1;
}

.header-center {
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
  text-align: center;
}

.header-title {
  font-size: 36rpx;
  font-weight: bold;
  color: #0071bc;
}

/* 成功状态栏 */
.success-banner {
  background-color: #0071bc;
  padding: 20rpx;
  text-align: center;
}

.success-text {
  font-size: 28rpx;
  color: #ffffff;
  font-weight: bold;
}

/* 内容区域 */
.content {
  flex: 1;
  padding: 50rpx;
  margin: 0;
  box-sizing: border-box;
  background: #fff;
  border-top-left-radius: 60rpx;
  border-top-right-radius: 60rpx;
}

/* 活动信息区域 */
.activity-info-section {
  background-color: #ffffff;
  padding: 30rpx;
  margin-bottom: 30rpx;
  box-sizing: border-box;
}

.activity-header {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  margin-bottom: 20rpx;
}

.activity-title {
  font-size: 28rpx;
  font-weight: bold;
  color: #333333;
  flex: 1;
  line-height: 1.4;
}

.activity-rules {
  font-size: 24rpx;
  color: #0071bc;
  margin-left: 20rpx;
}

.activity-detail {
  display: flex;
  flex-direction: row;
  justify-content: space-between;
  gap: 20rpx;
  margin-top: 40rpx;
}

.detail-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  flex: 1;
  gap: 16rpx;
}

.detail-icon {
  width: 40rpx;
  height: 40rpx;
  flex-shrink: 0;
}

.detail-text-wrapper {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8rpx;
}

.detail-text {
  font-size: 22rpx;
  color: #333333;
  line-height: 1.4;
  text-align: center;
}

.activity-desc {
  margin-top: 24rpx;
  padding-top: 10rpx;
  padding-bottom: 10rpx;
  border-top: 1rpx solid #e0e0e0;
  border-bottom: 1rpx solid #e0e0e0;
  box-sizing: border-box;
  width: 100%;
  overflow: hidden;
}

.activity-desc-text {
  font-size: 22rpx;
  color: #333333;
  line-height: 1.6;
  display: block;
}

/* 表单区域 */
.form-section {
  background-color: #ffffff;
  border-radius: 24rpx;
  padding: 30rpx;
  margin-bottom: 30rpx;
  box-sizing: border-box;
}

.section-title {
  display: block;
  font-size: 26rpx;
  color: #0071bc;
  margin-bottom: 25rpx;
  padding-bottom: 5rpx;
  border-bottom: 1rpx solid #e0e0e0;
}

.form-item {
  margin-bottom: 20rpx;
}

.form-item:last-child {
  margin-bottom: 0;
}

.form-label {
  display: block;
  font-size: 24rpx;
  color: #0071bc;
  margin-bottom: 16rpx;
  margin-left: 15rpx;
}

.form-input {
  width: 100%;
  height: 80rpx;
  background-color: #f5f5f5;
  border-radius: 8rpx;
  padding: 0 10rpx;
  font-size: 28rpx;
  color: #333333;
  box-sizing: border-box;
}

.phone-input-wrapper {
  position: relative;
}

.phone-input {
  padding-right: 160rpx;
}

.wechat-auth-text {
  position: absolute;
  right: 20rpx;
  top: 50%;
  transform: translateY(-50%);
  font-size: 24rpx;
  color: #0071bc;
  z-index: 1;
}

.wechat-auth-btn {
  position: absolute;
  right: 20rpx;
  top: 50%;
  transform: translateY(-50%);
  width: auto;
  height: auto;
  line-height: 1;
  padding: 0;
  margin: 0;
  background: transparent;
  border: none;
  font-size: 24rpx;
  color: #0071bc;
  z-index: 1;
}

.wechat-auth-btn::after {
  border: none;
}

.form-hint {
  display: block;
  font-size: 24rpx;
  color: #999999;
  margin-top: 12rpx;
}

/* 预约详情区域 */
.reservation-details-section {
  background-color: #ffffff;
  border: 1rpx solid #0071bc;
  border-radius: 24rpx;
  padding: 30rpx;
  margin-bottom: 30rpx;
  box-sizing: border-box;
}

.detail-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 24rpx 0;
  border-bottom: 1rpx solid #f0f0f0;
}

.detail-row:last-child {
  border-bottom: none;
}

.detail-label {
  font-size: 28rpx;
  color: #666666;
}

.detail-value {
  font-size: 28rpx;
  color: #333333;
  font-weight: 500;
}

/* 底部按钮 */
.footer {
  padding: 30rpx 50rpx 40rpx;
  background: linear-gradient(to top, #93d3f4, #fff);
  box-sizing: border-box;
}

.submit-btn {
  width: 100%;
  height: 88rpx;
  background-color: #0071bc;
  color: #ffffff;
  border: none;
  border-radius: 24rpx;
  font-size: 32rpx;
  font-weight: bold;
  line-height: 88rpx;
}

.submit-btn::after {
  border: none;
}

.cancel-btn {
  width: 100%;
  height: 88rpx;
  background-color: #cccccc;
  color: #ffffff;
  border: none;
  border-radius: 24rpx;
  font-size: 32rpx;
  font-weight: bold;
  line-height: 88rpx;
}

.cancel-btn::after {
  border: none;
}

/* 成功弹窗遮罩层 */
.success-modal-mask {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-color: rgba(0, 0, 0, 0.7);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 1000;
  animation: fadeIn 0.3s ease-in-out;
}

/* 成功弹窗内容 */
.success-modal-content {
  position: relative;
  width: 600rpx;
  max-width: 90%;
  display: flex;
  flex-direction: column;
  align-items: center;
  animation: scaleIn 0.3s ease-in-out;
}

/* 背景图片容器 */
.success-modal-bg-wrapper {
  position: relative;
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  padding-bottom: 150rpx;
}

/* 背景图片 */
.success-modal-bg {
  width: 600rpx;
  height: 800rpx;
  border-radius: 20rpx;
}

/* 关闭按钮 */
/* 关闭按钮（对齐 playlist-share.vue） */
.close-button {
  position: absolute;
  top: 20rpx;
  right: -20rpx;
  width: 60rpx;
  height: 60rpx;
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 1001;
  cursor: pointer;
}

.close-icon {
  width: 60rpx;
  height: 60rpx;
}

/* 吉祥物图片（对齐 playlist-share.vue） */
.success-modal-mascot {
  position: absolute;
  top: 32%;
  left: 50%;
  transform: translateX(-50%);
  width: 200rpx;
  height: 200rpx;
  z-index: 10;
}

/* 分享成功文字 */
.success-text {
  position: absolute;
  top: 65%;
  left: 50%;
  transform: translate(-50%, -50%);
  color: #ff0000;
  font-size: 66rpx;
  font-weight: bold;
  text-align: center;
  z-index: 10;
  text-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.2);
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}

.success-text.small {
  font-size: 42rpx;
}

.success-text text {
  display: block;
  line-height: 1.5;
}
/* 点击查看按钮 */
.lottery-button {
  position: absolute;
  bottom: 40rpx;
  left: 50%;
  transform: translateX(-50%);
  width: 400rpx;
  height: 88rpx;
  background: #ff0000;
  border-radius: 44rpx;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #ffffff;
  font-size: 36rpx;
  font-weight: bold;
  box-shadow: 0 8rpx 24rpx rgba(255, 0, 0, 0.4);
  transition: all 0.3s ease;
  z-index: 10;
}

.lottery-button:active {
  transform: translateX(-50%) scale(0.95);
  box-shadow: 0 4rpx 12rpx rgba(255, 0, 0, 0.3);
}

/* 弹窗淡入动画 */
@keyframes fadeIn {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

/* 弹窗缩放动画 */
@keyframes scaleIn {
  from {
    transform: scale(0.8);
    opacity: 0;
  }
  to {
    transform: scale(1);
    opacity: 1;
  }
}

/* 全局返回按钮样式 */
.global-back-button {
  width: 60rpx;
  height: 60rpx;
  background: #0071bc;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  margin-right: 15rpx;
}

.global-back-icon {
  color: white;
  font-size: 40rpx;
  font-weight: bold;
  line-height: 1;
}

.global-back-text {
  color: #000000;
  font-size: 28rpx;
}

.global-header-left {
  display: flex;
  align-items: center;
}

/* ========== 已预约界面专用样式 ========== */

/* 预约成功标签 */
.reserved-success-tag {
  display: inline-block;
  background-color: #4caf50;
  border-radius: 8rpx;
  padding: 0 16rpx 6rpx;
  margin-top: 20rpx;
  margin-bottom: 24rpx;
}

.reserved-success-text {
  font-size: 24rpx;
  color: #ffffff;
  font-weight: 500;
}

/* 已预约活动信息区域 */
.activity-info-reserved {
  padding-bottom: 30rpx;
}

.activity-detail-reserved {
  flex-direction: column;
  align-items: flex-start;
  gap: 20rpx;
  margin-top: 20rpx;
}

.detail-item-reserved {
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: 12rpx;
  width: 100%;
}

.detail-icon-reserved {
  width: 32rpx;
  height: 32rpx;
  flex-shrink: 0;
}

.detail-text-reserved {
  font-size: 26rpx;
  color: #333333;
  line-height: 1.4;
}

/* 分隔线 */
.reserved-divider {
  height: 1rpx;
  background-color: #e0e0e0;
  margin: 30rpx 0;
  width: 100%;
}

/* 已预约详情区域 */
.reservation-details-reserved {
  background-color: transparent;
  border: none;
  padding: 0;
  margin-bottom: 30rpx;
}

.section-title-reserved {
  display: block;
  font-size: 28rpx;
  color: #0071bc;
  margin-bottom: 20rpx;
  padding-bottom: 0;
  border-bottom: none;
}

.reservation-detail-card {
  background-color: #f5f5f5;
  border-radius: 16rpx;
  padding: 30rpx;
  box-sizing: border-box;
  margin-top: 0;
}

.detail-row-reserved {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 12rpx 0;
}

.detail-row-reserved:last-child {
  border-bottom: none;
}

.detail-label-reserved {
  font-size: 28rpx;
  color: #666666;
}

.detail-value-reserved {
  font-size: 28rpx;
  color: #333333;
  font-weight: 500;
}

/* 已预约取消按钮 */
.content-reserved ~ .footer .cancel-btn-reserved,
.footer .cancel-btn-reserved {
  background-color: #ffffff;
  color: #666666;
  border: 1rpx solid #cccccc;
  font-weight: normal;
}

.content-reserved ~ .footer .cancel-btn-reserved::after,
.footer .cancel-btn-reserved::after {
  border: 2rpx solid #cccccc;
}

/* 规则弹窗样式 */
.modal-overlay {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: rgba(0, 0, 0, 0.7);
  display: flex;
  justify-content: center;
  align-items: center;
  z-index: 9999;
}

/* 外层容器 */
.modal-outer {
  width: 92%;
  max-width: 600rpx;
  background: linear-gradient(to bottom, #add8e6, #b8e6ff, #fff);
  border-radius: 20rpx;
  overflow: hidden;
  box-shadow: 0 10rpx 30rpx rgba(0, 0, 0, 0.3);
  padding: 6rpx;
}

/* 外层标题区域 */
.modal-header-outer {
  padding: 30rpx;
  text-align: center;
  background: transparent;
}

.modal-title-outer {
  font-size: 36rpx;
  font-weight: bold;
  color: #1e90ff;
}

/* 内层容器 */
.modal-inner {
  background-color: #ffffff;
  border: #add8e6 solid 1rpx;
  border-radius: 14rpx;
  display: flex;
  flex-direction: column;
  max-height: 70vh;
  width: calc(100% - 60rpx);
  margin: 0 auto;
  margin-bottom: 30rpx;
}

/* 滚动内容区域 */
.modal-content-scroll {
  flex: 1;
  max-height: 50vh;
}

.modal-body {
  padding: 40rpx 30rpx 20rpx;
}

.rule-item {
  margin-bottom: 35rpx;
  padding-bottom: 25rpx;
  border-bottom: 1rpx solid #f0f0f0;
}

.rule-item:last-child {
  margin-bottom: 0;
  padding-bottom: 0;
  border-bottom: none;
}

.rule-title {
  display: block;
  font-size: 26rpx;
  font-weight: 600;
  color: #2c3e50;
  margin-bottom: 15rpx;
  line-height: 1.4;
}

.rule-detail {
  display: block;
  font-size: 24rpx;
  color: #5a6c7d;
  line-height: 1.6;
  padding-left: 20rpx;
  white-space: pre-line;
}

.rule-image-wrapper {
  margin: 20rpx 0 30rpx;
  display: flex;
  justify-content: center;
}

.rule-map-image {
  width: 100%;
  max-width: 620rpx;
  border-radius: 16rpx;
  box-shadow: 0 8rpx 24rpx rgba(0, 0, 0, 0.12);
}

.modal-footer {
  padding: 30rpx 40rpx 40rpx;
  text-align: center;
}

.modal-btn {
  width: 100%;
  height: 88rpx;
  background: linear-gradient(135deg, #ff6b6b, #ff5252);
  color: #ffffff;
  font-size: 30rpx;
  font-weight: 600;
  border: none;
  border-radius: 44rpx;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 4rpx 12rpx rgba(255, 107, 107, 0.3);
  transition: all 0.3s ease;
}

.modal-btn:active {
  transform: translateY(2rpx);
  box-shadow: 0 2rpx 8rpx rgba(255, 107, 107, 0.3);
}

.modal-btn::after {
  border: none;
}
</style>
